package basicobject

import (
	"fmt"
	"github.com/pkg/errors"
	"reflect"
	"yizhuoyan/go-study/pdfgo/handyio"
)

type BasicObject interface {
	Serialize(handyio.PdfRawWriter) error
	UnSerialize(handyio.PdfRawReader) error
}

func ReadrBasicObject(r handyio.PdfRawReader) (BasicObject, error) {
	b, err := r.NextByte()
	if err != nil {
		return nil, err
	}
	if err = r.IndexMoveTo(r.IndexCurrent() - 1); err != nil {
		return nil, err
	}
	switch b {
	case '[': //array
		return tryObjectUnSerialize(r, new(Array))
	case 't', 'f':
		return tryObjectUnSerialize(r, new(Boolean))
	case '<':
		return tryObjectUnSerialize(r, new(Dictionary), new(HexString))
	case '(':
		return tryObjectUnSerialize(r, new(ByteString))
	case '/':
		return tryObjectUnSerialize(r, new(Name))
	case 'n':
		return tryObjectUnSerialize(r, Null)
	case '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		return tryObjectUnSerialize(r, new(IndirectObjectReference), new(Integer), new(Real))
	case '.':
		return tryObjectUnSerialize(r, new(Real))
	}
	return nil, r.NotSupport("无法识别为BasicObject")
}

func tryObjectUnSerialize(r handyio.PdfRawReader, objs ...BasicObject) (BasicObject, error) {
	startAt := r.IndexCurrent()
	for _, one := range objs {
		if err := one.UnSerialize(r); err != nil {
			if r.IsNotSupportError(err) {
				continue
			}
			_ = r.IndexMoveTo(startAt)
			return nil, err
		}
		return one, nil
	}
	var types = make([]string, len(objs))
	for i, one := range objs {
		types[i] = reflect.TypeOf(one).String()
	}
	return nil, errors.New(fmt.Sprintf("无法识别为BasicObject类型:%v", types))
}
